#include <mutex>

#include "common/more/time.h"

#include "item_history.h"

namespace Elements
{

ItemHistory::ItemHistory(const ItemHistory& other)
    : Element(other)
    , m_itemId(other.m_itemId)
    , m_userId(other.m_userId)
    , m_timestamp(other.m_timestamp)
    , m_diff(other.m_diff)
{
}

bool ItemHistory::isSame(Element* const other) const
{
    const auto otherElement = dynamic_cast<ItemHistory const*>(other);
    if (nullptr == otherElement)
        return false;

    return bool(
        m_id == otherElement->m_id
        && m_itemId == otherElement->m_itemId
        && m_userId == otherElement->m_userId
        && m_timestamp == otherElement->m_timestamp
        && m_diff == otherElement->m_diff
    );
}

Common::Json ItemHistory::toJson() const
{
    std::shared_lock locker(m_lock);
    Common::Json result;
    result["id"] = m_id;
    result["elementType"] = unsigned(elementType());
    result["itemId"] = m_itemId;
    result["userId"] = m_userId;
    result["timestamp"] = m_timestamp;
    result["diff"] = m_diff;
    return result;
}

void ItemHistory::fromJson(const Common::Json& json)
{
    std::shared_lock locker(m_lock);
    m_id = json["id"].get<unsigned>();
    m_itemId = json["itemId"].get<unsigned>();
    m_userId = json["userId"].get<unsigned>();
    m_timestamp = json["timestamp"].get<std::time_t>();
    m_diff = json["diff"].get<std::string>();
}

Element* ItemHistory::clone() const
{
    return new ItemHistory(*this);
}

ElementType ItemHistory::elementType() const
{
    return ElementType::ItemHistory;
}

unsigned ItemHistory::itemId() const
{
    std::shared_lock locker(m_lock);
    return m_itemId;
}

void ItemHistory::setItemId(unsigned value)
{
    std::unique_lock locker(m_lock);
    m_itemId = value;
}

unsigned ItemHistory::userId() const
{
    std::shared_lock locker(m_lock);
    return m_userId;
}

void ItemHistory::setUserId(unsigned value)
{
    std::unique_lock locker(m_lock);
    m_userId = value;
}

std::time_t ItemHistory::timestamp() const
{
    std::shared_lock locker(m_lock);
    return m_timestamp;
}

void ItemHistory::setTimestamp(const std::time_t& value)
{
    std::unique_lock locker(m_lock);
    m_timestamp = value;
}

std::string ItemHistory::diff() const
{
    std::shared_lock locker(m_lock);
    return m_diff;
}

void ItemHistory::setDiff(const std::string& value)
{
    std::unique_lock locker(m_lock);
    m_diff = value;
}

} // namespace Elements
